﻿using System;
using System.Collections.Generic;
using System.Linq;
using StoCombatLogHUD.Parsing;

namespace StoCombatLogHUD.Statistics.StatisticsEntries
{
	/// <summary>
	/// A statistics entry that automatically calulates it's value per second.
	/// </summary>
	public class AutoCalculatedStatisticsEntry : IStatisticsEntry
	{
		/// <summary>
		/// The combat log entries
		/// </summary>
		private readonly List<CombatLogEntry> combatLogEntries = new List<CombatLogEntry>();

		/// <summary>
		/// Adds the combat log entry.
		/// </summary>
		/// <param name="entry">The entry.</param>
		public void AddCombatLogEntry(CombatLogEntry entry)
		{
			lock (combatLogEntries)
				combatLogEntries.Add(entry);
		}

		/// <summary>
		/// Gets the <see cref="StatisticValue"/> with the specified flags.
		/// </summary>
		/// <value>
		/// The <see cref="StatisticValue"/>.
		/// </value>
		/// <param name="flags">The flags.</param>
		/// <returns></returns>
		public StatisticValue this[CombatLogEntry.CombatFlags flags]
		{
			get
			{
				var totalValue = 0.0;
				var startTimeStamp = new DateTime();
				var endTimeStamp = new DateTime();

				lock (combatLogEntries)
				{
					foreach (var entry in combatLogEntries.Where(entry => entry.Flags.HasFlag(flags)).OrderBy(entry => entry.Timestamp))
					{
						if (startTimeStamp.Ticks == 0)
							startTimeStamp = entry.Timestamp;
						endTimeStamp = entry.Timestamp;

						totalValue += entry.GetEffectiveValue();
					}
				}

				// Calculate value per second
				var valuePerSecond = (startTimeStamp == endTimeStamp)
					                     ? 0
					                     : totalValue/(endTimeStamp - startTimeStamp).TotalSeconds;

				return new StatisticValue {TotalValue = totalValue, ValuePerSecond = valuePerSecond};
			}
		}

		/// <summary>
		/// Returns the number of entries matching the given <paramref name="flags" />.
		/// </summary>
		/// <param name="flags">The flags.</param>
		/// <returns></returns>
		/// <exception cref="System.NotImplementedException"></exception>
		public int Count(CombatLogEntry.CombatFlags flags)
		{
			return combatLogEntries.Count(entry => entry.Flags.HasFlag(flags));
		}
	}
}
